From fa477fdb3f1c3ecdb0d59f3460301f9fe3e603ab Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild.aw" Date: Mon, 27 Feb 2006 14:00:33 -0700 Subject: [PATCH] [IA64] fix SMP bug for vhpt vhpt_paddr & vhpt_pend are now per-cpu variables, since VHPT is allocated per cpu. This should really improve stability. Signed-off-by: Tristan Gingold --- xen/arch/ia64/xen/domain.c | 10 ++++++---- xen/arch/ia64/xen/regionreg.c | 11 ++++++----- xen/arch/ia64/xen/vhpt.c | 20 ++++++++++++-------- xen/include/asm-ia64/vhpt.h | 5 +++++ 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index f0d5a4ff97..aead3cf442 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #define CONFIG_DOMAIN0_CONTIGUOUS @@ -399,7 +400,6 @@ struct page * assign_new_domain_page(struct domain *d, unsigned long mpaddr) pud_t *pud; pmd_t *pmd; pte_t *pte; -extern unsigned long vhpt_paddr, vhpt_pend; if (!mm->pgd) { printk("assign_new_domain_page: domain pgd must exist!\n"); @@ -433,9 +433,11 @@ extern unsigned long vhpt_paddr, vhpt_pend; printf("assign_new_domain_page: Can't alloc!!!! Aaaargh!\n"); return(p); } -if (unlikely(page_to_maddr(p) > vhpt_paddr && page_to_maddr(p) < vhpt_pend)) { - printf("assign_new_domain_page: reassigned vhpt page %p!!\n",page_to_maddr(p)); -} + if (unlikely(page_to_maddr(p) > __get_cpu_var(vhpt_paddr) + && page_to_maddr(p) < __get_cpu_var(vhpt_pend))) { + printf("assign_new_domain_page: reassigned vhpt page %p!!\n", + page_to_maddr(p)); + } set_pte(pte, pfn_pte(page_to_maddr(p) >> PAGE_SHIFT, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX))); } diff --git a/xen/arch/ia64/xen/regionreg.c b/xen/arch/ia64/xen/regionreg.c index 0629aa2d4e..766572af93 100644 --- a/xen/arch/ia64/xen/regionreg.c +++ b/xen/arch/ia64/xen/regionreg.c @@ -211,7 +211,6 @@ int set_one_rr(unsigned long rr, unsigned long val) unsigned long rreg = REGION_NUMBER(rr); ia64_rr rrv, newrrv, memrrv; unsigned long newrid; - extern unsigned long vhpt_paddr; if (val == -1) return 1; @@ -249,10 +248,12 @@ int set_one_rr(unsigned long rr, unsigned long val) newrrv.rid = newrid; newrrv.ve = 1; // VHPT now enabled for region 7!! newrrv.ps = PAGE_SHIFT; - if (rreg == 0) v->arch.metaphysical_saved_rr0 = - vmMangleRID(newrrv.rrval); - if (rreg == 7) ia64_new_rr7(vmMangleRID(newrrv.rrval),v->vcpu_info, - v->arch.privregs, vhpt_paddr, pal_vaddr); + if (rreg == 0) + v->arch.metaphysical_saved_rr0 = vmMangleRID(newrrv.rrval); + else if (rreg == 7) + ia64_new_rr7(vmMangleRID(newrrv.rrval),v->vcpu_info, + v->arch.privregs, __get_cpu_var(vhpt_paddr), + pal_vaddr); else set_rr(rr,newrrv.rrval); #endif return 1; diff --git a/xen/arch/ia64/xen/vhpt.c b/xen/arch/ia64/xen/vhpt.c index 62b272d849..3050ebe769 100644 --- a/xen/arch/ia64/xen/vhpt.c +++ b/xen/arch/ia64/xen/vhpt.c @@ -15,7 +15,8 @@ #include #include -unsigned long vhpt_paddr, vhpt_pend, vhpt_pte; +DEFINE_PER_CPU (unsigned long, vhpt_paddr); +DEFINE_PER_CPU (unsigned long, vhpt_pend); void vhpt_flush(void) { @@ -77,12 +78,12 @@ void vhpt_flush_address(unsigned long vadr, unsigned long addr_range) } #endif -void vhpt_map(void) +static void vhpt_map(unsigned long pte) { unsigned long psr; psr = ia64_clear_ic(); - ia64_itr(0x2, IA64_TR_VHPT, VHPT_ADDR, vhpt_pte, VHPT_SIZE_LOG2); + ia64_itr(0x2, IA64_TR_VHPT, VHPT_ADDR, pte, VHPT_SIZE_LOG2); ia64_set_psr(psr); ia64_srlz_i(); } @@ -122,6 +123,7 @@ void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte, unsigned long void vhpt_init(void) { unsigned long vhpt_total_size, vhpt_alignment; + unsigned long paddr, pte; struct page_info *page; #if !VHPT_ENABLED return; @@ -141,11 +143,13 @@ void vhpt_init(void) printf("vhpt_init: can't allocate VHPT!\n"); while(1); } - vhpt_paddr = page_to_maddr(page); - vhpt_pend = vhpt_paddr + vhpt_total_size - 1; - printf("vhpt_init: vhpt paddr=%p, end=%p\n",vhpt_paddr,vhpt_pend); - vhpt_pte = pte_val(pfn_pte(vhpt_paddr >> PAGE_SHIFT, PAGE_KERNEL)); - vhpt_map(); + paddr = page_to_maddr(page); + __get_cpu_var(vhpt_paddr) = paddr; + __get_cpu_var(vhpt_pend) = paddr + vhpt_total_size - 1; + printf("vhpt_init: vhpt paddr=%p, end=%p\n", + paddr, __get_cpu_var(vhpt_pend)); + pte = pte_val(pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL)); + vhpt_map(pte); ia64_set_pta(VHPT_ADDR | (1 << 8) | (VHPT_SIZE_LOG2 << 2) | VHPT_ENABLED); vhpt_flush(); diff --git a/xen/include/asm-ia64/vhpt.h b/xen/include/asm-ia64/vhpt.h index d4dfce6b8a..465065b351 100644 --- a/xen/include/asm-ia64/vhpt.h +++ b/xen/include/asm-ia64/vhpt.h @@ -121,6 +121,11 @@ extern void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte, extern void vhpt_insert (unsigned long vadr, unsigned long ptr, unsigned logps); extern void vhpt_flush(void); + +/* Currently the VHPT is allocated per CPU. */ +DECLARE_PER_CPU (unsigned long, vhpt_paddr); +DECLARE_PER_CPU (unsigned long, vhpt_pend); + #endif /* !__ASSEMBLY */ #if !VHPT_ENABLED -- 2.30.2